﻿Imports Brainworklite.Core.WinForms
Imports Brainworklite.Core.WinForms.WinformsExtensions
Imports Brainworklite.Core.StringExtensions
Imports Brainworklite.Core
Imports System.Text
Imports System.Text.RegularExpressions
Public Class frmMain
    Dim isFinshLoad As Boolean = False
    Sub updateSettings() Handles lblFolderOut.TextChanged
        If isFinshLoad Then
            My.Settings.lblFolderOut = Me.lblFolderOut.Text
            My.Settings.Save()
        End If

    End Sub

    Sub LoadSettings()
        Me.lblFolderOut.Text = My.Settings.lblFolderOut
    End Sub
    Private da As New DataAccess()

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        LoadSettings()
        Dim ddl As New ComboBox
        Dim tables = da.getTables()
        WinFormsHelper.LoadCheckBox(Me.chkList, tables, "Name")

        isFinshLoad = True

        'Me.chkList.da
    End Sub

    Private Sub btnSelectAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSelectAll.Click
        Me.chkList.selectAll()
    End Sub

    Private Sub btnCambiar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCambiar.Click
        Me.FolderBrowserDialog1.ShowDialog()
        If Not Me.FolderBrowserDialog1.SelectedPath.IsNothing() Then
            Me.lblFolderOut.Text = Me.FolderBrowserDialog1.SelectedPath
        End If
    End Sub

    Private Sub btnGenerar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGenerar.Click
        For Each item In Me.chkList.CheckedIndices

            CreateClass(Me.chkList.Items(item))
        Next
        MsgBox("Listo")
        Dim p = New Process()
        ' p.Start(Me.lblFolderOut.Text)
    End Sub

    Private Sub CreateClass(ByVal TableName As String)
        Dim dFields = da.getFields(TableName).AsEnumerable()
        Dim tblds = da.getEmptyDataSet(TableName)
        Dim lFields As New List(Of FieldsDefinitionClass)

        For Each item As DataColumn In tblds.Tables(0).Columns
            Dim colName = item.ColumnName
            Dim fl = dFields.Where(Function(x) x.Field(Of String)("Name").Equals(colName)).First()
            Dim fld = New FieldsDefinitionClass()

            fld.DefaultValue = DataHelper.getNotDBNull(fl("COLUMN_DEFAULT"))
            fld.ColumnName = colName
            fld.FieldName = "_" & colName.Replace(" "c, "_")
            fld.FieldType = item.DataType
            fld.ForeingTable = DataHelper.getNotDBNull(fl("ReferenceTableName"))
            fld.ForingColumn = DataHelper.getNotDBNull(fl("ReferenceColumnName"))
            fld.IsFK = (Not fld.ForeingTable.IsNothing()) AndAlso (Not fld.ForingColumn.IsNothing())
            fld.isNullable = CBool(DataHelper.getNotDBNull(fl("is_nullable")))
            fld.IsPK = CBool(DataHelper.getNotDBNull(fl("is_identity")))
            fld.PropertyName = colName.Replace(" "c, "_")
            fld.dbType = DataHelper.getNotDBNull(fl("DataType"))
            lFields.Add(fld)
        Next
        createClassFromTemplate(TableName, lFields)
    End Sub

    Private Function getTemplatePathString() As String
        Dim pt = System.IO.Path.Combine(My.Application.Info.DirectoryPath, "TemplateClass.txt")
        Using sr As New IO.StreamReader(pt)
            getTemplatePathString = sr.ReadToEnd()
        End Using
    End Function

    Private Function getSavePath() As String
        If Not System.IO.Directory.Exists(Me.lblFolderOut.Text) Then
            System.IO.Directory.CreateDirectory(Me.lblFolderOut.Text)
        End If

        Dim pth As String
        If (chkOverrideFiles.Checked) Then
            pth = Me.lblFolderOut.Text
        Else
            pth = IO.Path.Combine(Me.lblFolderOut.Text, Date.Now.ToString("ddMMyyyyhhmm"))
        End If

        If Not System.IO.Directory.Exists(pth) Then
            System.IO.Directory.CreateDirectory(pth)
        End If
        Return pth
    End Function

    Private Function getAttributes(ByVal lFields As List(Of FieldsDefinitionClass)) As Dictionary(Of String, String)
        Dim sb As StringBuilder
        Dim descId = 0
        Dim itemsCount = 0
        Dim _PutAttributes = New Dictionary(Of String, String)
        For Each field In lFields
            sb = New StringBuilder()
            If field.IsPK Then
                sb.AppendFormat("{0}{1}{1}<PrimaryKey()> _  ", _
                                     vbCrLf, _
                                     vbTab)
            End If
            If field.PropertyName.ToLower().Contains("descripcion") OrElse _
            field.PropertyName.ToLower().Contains("nombre") Then
                sb.AppendFormat("{0}{1}{1}<DescriptionPart({2})> _  ", _
                                    vbCrLf, _
                                    vbTab, descId)
                descId = descId + 1
            End If

            'isListViewPartAttribute

            If field.IsFK Then

                sb.AppendFormat("{0}{1}{1}  <IsCollection(""{2}"", ""{3},{4}"")> _  ", _
                                    vbCrLf, _
                                    vbTab, field.ForeingTable, field.PropertyName, IIf(String.IsNullOrEmpty(field.ForingColumn), field.PropertyName, field.ForingColumn))
            End If

            Dim labels As String = field.PropertyName
            If labels.IndexOf("_") > 0 Then
                labels = labels.Substring(labels.IndexOf("_"))
            End If
            labels = labels.Replace("_"c, " ").Trim()

            If field.IsFK Then
                labels += " de " & field.ForeingTable.Replace("_"c, " ").Trim()
            End If

            sb.AppendFormat("{0}{1}{1}<Label(""{2}"")> _  ", _
                                     vbCrLf, _
                                     vbTab, Regex.Replace(labels, "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", "$1 "))

            If Not field.IsFK Then
                sb.AppendFormat("{0}{1}{1}<isListViewPart({2})> _  ", _
                                    vbCrLf, _
                                    vbTab, itemsCount)
                descId = descId + 1
            End If

            If Not field.isNullable Then
                sb.AppendFormat("{0}{1}{1}<RequiredField(""El campo: {2} es requerido"")> _  ", _
                                   vbCrLf, _
                                   vbTab, labels)
                'Attribute
            End If

            itemsCount += 1
            _PutAttributes.Add(field.PropertyName, sb.ToString())
        Next

        If descId = 0 Then
            Dim pkName = lFields.Where(Function(x) x.IsPK)
            If pkName.Any() Then
                Dim s = _PutAttributes(pkName.FirstOrDefault().PropertyName)
                s += String.Format("{0}{1}{1}<DescriptionPart({2})> _  ", _
                                    vbCrLf, _
                                    vbTab, descId)
                _PutAttributes(pkName.FirstOrDefault().PropertyName) = s
            End If
        End If
        Return _PutAttributes
    End Function

    Private Sub createClassFromTemplate(ByVal className As String, ByVal lFields As List(Of FieldsDefinitionClass))
        Dim cls = getTemplatePathString()
        cls = cls.Replace("{ClassName}", className)
        cls = cls.Replace("{ConstructorCode}", vbTab & vbTab & "MyBase.New()")

        Dim fieldsCollection As New System.Text.StringBuilder()
        Dim propertiesCollection As New System.Text.StringBuilder()
        Dim att = getAttributes(lFields)
        For Each item In lFields
            fieldsCollection.AppendFormat("{1}{1}Private {2} As {3}{4}{0}", _
                                      vbCrLf, _
                                      vbTab, _
                                      item.FieldName, _
                                      item.FieldType.Name, _
                                      IIf(item.isNullable, "", "?") _
                                      )
            propertiesCollection.AppendFormat("{0}{1}", att(item.PropertyName), vbCrLf)
            propertiesCollection.AppendFormat("{1}{1}Public Property {2}() As {3}{4}{0}", _
                                      vbCrLf, _
                                      vbTab, _
                                      item.PropertyName, _
                                      item.FieldType.Name, _
                                      IIf(item.isNullable, "", "?") _
                                      )
            propertiesCollection.AppendFormat("{1}{1}{1}Get{0}", vbCrLf, vbTab)
            propertiesCollection.AppendFormat("{1}{1}{1}{1}Return {2}{0}", vbCrLf, vbTab, item.FieldName)
            propertiesCollection.AppendFormat("{1}{1}{1}End Get{0}", vbCrLf, vbTab)

            propertiesCollection.AppendFormat("{1}{1}{1}Set(value As {2}{3}){0}", _
                                              vbCrLf, _
                                              vbTab, _
                                              item.FieldType.Name, _
                                              IIf(item.isNullable, "", "?"))

            propertiesCollection.AppendFormat("{1}{1}{1}{1}{2} = value{0}", vbCrLf, vbTab, item.FieldName)

            propertiesCollection.AppendFormat("{1}{1}{1}End Set{0}", vbCrLf, vbTab)

            propertiesCollection.AppendFormat("{1}{1}{1}End Property{0}", vbCrLf, vbTab)
        Next

        cls = cls.Replace("{FieldsCollection}", fieldsCollection.ToString())
        cls = cls.Replace("{PropertiesCollection}", propertiesCollection.ToString())
        cls = cls.Replace(" String?", " String")

        If chkOverrideFiles.Checked AndAlso _
        IO.File.Exists(IO.Path.Combine(getSavePath(), className & ".vb")) Then
            IO.File.Delete(IO.Path.Combine(getSavePath(), className & ".vb"))
        End If

        Using sw As New IO.StreamWriter(IO.Path.Combine(getSavePath(), className & ".vb"), False)
            sw.Write(cls)
        End Using
    End Sub



    Public Class FieldsDefinitionClass
        Public dbType As String
        Public ColumnName As String
        Public FieldName As String
        Public PropertyName As String
        Public FieldType As Type
        Public ForeingTable As String
        Public ForingColumn As String
        Public IsPK As Boolean
        Public IsFK As Boolean
        Public DefaultValue As Object
        Public isNullable As Boolean

    End Class


End Class
